package view;

import model.StudentProfile;
import service.ScheduleService;
import service.StudentService;
import service.ClassService;
import model.User;
import service.TeacherService;
import view.common.MultiLineCellRenderer;
import utils.DatabaseUtil;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class SchedulePanel extends JPanel {
    private static final Font TITLE_FONT = new Font("微软雅黑", Font.BOLD, 14);
    private static final Font CONTENT_FONT = new Font("微软雅黑", Font.PLAIN, 13);
    private static final String[] COLUMN_NAMES = {"节次", "周一", "周二", "周三", "周四", "周五"};
    private static final String[] ROW_HEADERS = {
        "第一节 (08:00-08:45)",    // 第一大节的第一小节
        "第二节 (08:55-09:40)",    // 第一大节的第二小节
        "第三节 (10:00-10:45)",    // 第二大节的第一小节
        "第四节 (10:55-11:40)",    // 第二大节的第二小节
        "第五节 (14:00-14:45)",    // 第三大节的第一小节
        "第六节 (14:55-15:40)",    // 第三大节的第二小节
        "第七节 (16:00-16:45)",    // 第四大节的第一小节
        "第八节 (16:55-17:40)",    // 第四大节的第二小节
        "第九节 (19:00-19:45)",    // 第五大节的第一小节
        "第十节 (19:55-20:40)"     // 第五大节的第二小节
    };
    
    private JTable scheduleTable;
    private DefaultTableModel tableModel;
    private ScheduleService scheduleService;
    private ClassService classService;
    private TeacherService teacherService;
    private JToolBar toolBar;
    private int userId;
    private String userRole;
    private JComboBox<String> viewTypeCombo;
    private JComboBox<String> targetCombo;
    private Map<String, Integer> classIdMap = new HashMap<>();
    private Map<String, Integer> teacherIdMap = new HashMap<>();
    private List<Map<String, Object>> currentSchedule = new ArrayList<>();
    
    public SchedulePanel(int userId, String userRole) {
        this.userId = userId;
        this.userRole = userRole;
        this.scheduleService = new ScheduleService();
        this.classService = new ClassService();
        this.teacherService = new TeacherService();
        
        initComponents();        // 先初始化基本组件
        initViewControls();      // 再初始化查看控件
        loadSchedule();          // 最后加载数据
    }
    
    private void initComponents() {
        setLayout(new BorderLayout(10, 10));
        setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        
        // 初始化工具栏
        toolBar = new JToolBar();
        toolBar.setFloatable(false);
        toolBar.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        add(toolBar, BorderLayout.NORTH);
        
        // 创建标题面板
        JPanel titlePanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        JLabel titleLabel = new JLabel();
        titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 18));
        
        // 根据用户角色设置不同的标题
        if ("STUDENT".equals(userRole)) {
            titleLabel.setText("我的课表");
        } else if ("TEACHER".equals(userRole)) {
            titleLabel.setText("教师课表");
        } else {
            titleLabel.setText("课程表管理");
        }
        
        titlePanel.add(titleLabel);
        add(titlePanel, BorderLayout.NORTH);
        
        // 创建一个包含工具栏和标题的面板
        JPanel topPanel = new JPanel(new BorderLayout());
        topPanel.add(titlePanel, BorderLayout.NORTH);
        topPanel.add(toolBar, BorderLayout.CENTER);
        add(topPanel, BorderLayout.NORTH);
        
        // 创建课表表格
        DefaultTableModel model = createEmptyTableModel();
        scheduleTable = new JTable(model);
        scheduleTable.setRowHeight(50);  // 统一行高
        scheduleTable.getColumnModel().getColumn(0).setPreferredWidth(150);  // 第一列宽度
        
        // 设置表格样式
        scheduleTable.setFont(CONTENT_FONT);
        scheduleTable.getTableHeader().setFont(TITLE_FONT);
        
        // 添加到滚动面板
        add(new JScrollPane(scheduleTable), BorderLayout.CENTER);
        
        // 加载课表数据
        loadScheduleData();
    }
    
    private void loadScheduleData() {
        // 清空现有数据
        for (int i = 0; i < scheduleTable.getRowCount(); i++) {
            for (int j = 1; j < scheduleTable.getColumnCount(); j++) {
                scheduleTable.setValueAt("", i, j);
            }
        }
        
        if ("STUDENT".equals(userRole)) {
            // 学生课表显示逻辑
            loadStudentSchedule();
        } else if ("TEACHER".equals(userRole)) {
            // 教师课表显示逻辑
            loadTeacherSchedule();
        } else {
            // 管理员课表管理逻辑
            loadAdminSchedule();
        }
    }
    
    private void loadStudentSchedule() {
        // 从服务层获取课表数据
        List<Map<String, Object>> schedules = scheduleService.getStudentSchedule(userId);
        displayScheduleData(schedules);
    }
    
    private void loadTeacherSchedule() {
        // 从服务层获取课表数据
        List<Map<String, Object>> schedules = scheduleService.getTeacherSchedule(userId);
        // 临时设置角色为 TEACHER，以便正确显示班级信息
        String originalRole = this.userRole;
        this.userRole = "TEACHER";
        displayScheduleData(schedules);
        this.userRole = originalRole;  // 恢复原始角色
    }
    
    private void loadAdminSchedule() {
        if (viewTypeCombo == null || targetCombo == null) {
            return;
        }
        
        if (viewTypeCombo.getSelectedIndex() == 0) {
            // 查看班级课表
            String className = (String) targetCombo.getSelectedItem();
            Integer classId = classIdMap.get(className);
            if (classId != null) {
                loadClassSchedule(classId);
            }
        } else {
            // 查看教师课表时，需要显示班级信息
            String teacherName = (String) targetCombo.getSelectedItem();
            Integer teacherId = teacherIdMap.get(teacherName);
            if (teacherId != null) {
                loadTeacherSchedule(teacherId);  // 这里会临时切换角色
            }
        }
    }
    
    private void loadClassSchedule(int classId) {
        // 从服务层获取课表数据
        List<Map<String, Object>> schedules = scheduleService.getClassSchedule(classId);
        displayScheduleData(schedules);
    }
    
    private void loadTeacherSchedule(int teacherId) {
        // 从服务层获取课表数据
        List<Map<String, Object>> schedules = scheduleService.getTeacherSchedule(teacherId);
        // 临时设置角色为 TEACHER，以便正确显示班级信息
        String originalRole = this.userRole;
        this.userRole = "TEACHER";
        displayScheduleData(schedules);
        this.userRole = originalRole;  // 恢复原始角色
    }
    
    private void initViewControls() {
        // 只有管理员需要查看控件
        if (!"ADMIN".equals(userRole)) {
            return;
        }
        
        JPanel viewPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5));
        
        // 查看类型选择
        viewTypeCombo = new JComboBox<>(new String[]{"班级课表", "教师课表"});
        viewTypeCombo.setFont(CONTENT_FONT);
        viewTypeCombo.addActionListener(e -> updateTargetCombo());
        
        // 目标选择（班级或教师）
        targetCombo = new JComboBox<>();
        targetCombo.setFont(CONTENT_FONT);
        targetCombo.addActionListener(e -> loadSchedule());
        
        // 添加排课按钮
        JButton autoScheduleBtn = new JButton("自动排课");
        JButton manualScheduleBtn = new JButton("手动排课");
        JButton showUnscheduledBtn = new JButton("查看未排课");
        
        autoScheduleBtn.setFont(CONTENT_FONT);
        manualScheduleBtn.setFont(CONTENT_FONT);
        showUnscheduledBtn.setFont(CONTENT_FONT);
        
        autoScheduleBtn.addActionListener(e -> showAutoScheduleDialog());
        manualScheduleBtn.addActionListener(e -> showManualScheduleDialog());
        showUnscheduledBtn.addActionListener(e -> showUnscheduledClasses());
        
        viewPanel.add(new JLabel("查看类型："));
        viewPanel.add(viewTypeCombo);
        viewPanel.add(new JLabel("选择："));
        viewPanel.add(targetCombo);
        viewPanel.add(autoScheduleBtn);
        viewPanel.add(manualScheduleBtn);
        viewPanel.add(showUnscheduledBtn);
        
        // 添加到工具栏
        toolBar.add(viewPanel);
        
        // 初始化数据
        updateTargetCombo();
    }
    
    private void updateTargetCombo() {
        targetCombo.removeAllItems();
        classIdMap.clear();
        teacherIdMap.clear();
        
        if (viewTypeCombo.getSelectedIndex() == 0) {
            // 加载班级列表
            List<model.Class> classes = classService.getAllClasses();
            for (model.Class cls : classes) {
                targetCombo.addItem(cls.getClassName());
                classIdMap.put(cls.getClassName(), cls.getId());
            }
        } else {
            // 加载教师列表
            List<User> teachers = teacherService.getAllTeachers();
            for (User teacher : teachers) {
                targetCombo.addItem(teacher.getName());
                teacherIdMap.put(teacher.getName(), teacher.getId());
            }
        }
    }
    
    private void loadSchedule() {
        if (viewTypeCombo == null || targetCombo == null) {
            return;
        }
        
        if (viewTypeCombo.getSelectedIndex() == 0) {
            // 查看班级课表
            String className = (String) targetCombo.getSelectedItem();
            updateTitle(className + " 课程表");
            Integer classId = classIdMap.get(className);
            if (classId != null) {
                currentSchedule = scheduleService.getClassSchedule(classId);
                displayScheduleData(currentSchedule);
            }
        } else {
            // 查看教师课表
            String teacherName = (String) targetCombo.getSelectedItem();
            updateTitle(teacherName + " 老师课程表");
            Integer teacherId = teacherIdMap.get(teacherName);
            if (teacherId != null) {
                currentSchedule = scheduleService.getTeacherSchedule(teacherId);
                String originalRole = userRole;
                userRole = "TEACHER";
                displayScheduleData(currentSchedule);
                userRole = originalRole;
            }
        }
    }
    
    private void showAutoScheduleDialog() {
        JDialog dialog = new JDialog((Frame)SwingUtilities.getWindowAncestor(this), "自动排课", true);
        dialog.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 5, 5, 5);
        
        // 班级选择
        gbc.gridx = 0; gbc.gridy = 0;
        dialog.add(new JLabel("选择班级："), gbc);
        
        gbc.gridx = 1;
        JComboBox<ClassItem> classCombo = new JComboBox<>();
        List<Map<String, Object>> classes = classService.getAllClassesForCombo();
        for (Map<String, Object> cls : classes) {
            classCombo.addItem(new ClassItem(
                (Integer)cls.get("id"), 
                cls.get("className").toString()
            ));
        }
        dialog.add(classCombo, gbc);
        
        // 按钮面板
        gbc.gridx = 0; gbc.gridy = 1;
        gbc.gridwidth = 2;
        JPanel buttonPanel = new JPanel();
        JButton confirmButton = new JButton("开始排课");
        JButton cancelButton = new JButton("取消");
        
        confirmButton.addActionListener(e -> {
            if (classCombo.getSelectedItem() == null) {
                JOptionPane.showMessageDialog(dialog, "请选择班级！");
                return;
            }
            
            ClassItem selectedClass = (ClassItem)classCombo.getSelectedItem();
            if (scheduleService.autoSchedule(selectedClass.getId())) {
                dialog.dispose();
                loadSchedule();
                JOptionPane.showMessageDialog(this, "自动排课成功！");
            } else {
                JOptionPane.showMessageDialog(dialog, "自动排课失败！", 
                    "错误", JOptionPane.ERROR_MESSAGE);
            }
        });
        
        cancelButton.addActionListener(e -> dialog.dispose());
        
        buttonPanel.add(confirmButton);
        buttonPanel.add(cancelButton);
        dialog.add(buttonPanel, gbc);
        
        // 设置字体
        classCombo.setFont(new Font("微软雅黑", Font.PLAIN, 13));
        confirmButton.setFont(new Font("微软雅黑", Font.PLAIN, 13));
        cancelButton.setFont(new Font("微软雅黑", Font.PLAIN, 13));
        
        dialog.pack();
        dialog.setLocationRelativeTo(this);
        dialog.setVisible(true);
    }
    
    private void showManualScheduleDialog() {
        JDialog dialog = new JDialog((Frame)SwingUtilities.getWindowAncestor(this), "手动排课", true);
        dialog.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 5, 5, 5);
        
        // 班级选择
        gbc.gridx = 0; gbc.gridy = 0;
        dialog.add(new JLabel("选择班级："), gbc);
        
        gbc.gridx = 1;
        JComboBox<ClassItem> classCombo = new JComboBox<>();
        List<Map<String, Object>> classes = classService.getAllClassesForCombo();
        for (Map<String, Object> cls : classes) {
            classCombo.addItem(new ClassItem(
                (Integer)cls.get("id"), 
                cls.get("className").toString()
            ));
        }
        dialog.add(classCombo, gbc);
        
        // 课程选择
        gbc.gridx = 0; gbc.gridy = 1;
        dialog.add(new JLabel("选择课程："), gbc);
        
        gbc.gridx = 1;
        JComboBox<SubjectTeacherItem> subjectCombo = new JComboBox<>();
        classCombo.addActionListener(e -> {
            ClassItem selectedClass = (ClassItem)classCombo.getSelectedItem();
            if (selectedClass != null) {
                loadSubjectTeachers(subjectCombo, selectedClass.getId());
            }
        });
        dialog.add(subjectCombo, gbc);
        
        // 时间选择
        gbc.gridx = 0; gbc.gridy = 2;
        dialog.add(new JLabel("星期："), gbc);
        
        gbc.gridx = 1;
        JComboBox<String> weekdayCombo = new JComboBox<>(
            new String[]{"周一", "周二", "周三", "周四", "周五"}
        );
        dialog.add(weekdayCombo, gbc);
        
        gbc.gridx = 0; gbc.gridy = 3;
        dialog.add(new JLabel("节次："), gbc);
        
        gbc.gridx = 1;
        JComboBox<String> periodCombo = new JComboBox<>(ROW_HEADERS);
        dialog.add(periodCombo, gbc);
        
        // 教室选择
        gbc.gridx = 0; gbc.gridy = 4;
        dialog.add(new JLabel("教室："), gbc);
        
        gbc.gridx = 1;
        JComboBox<ClassroomItem> roomCombo = new JComboBox<>();
        weekdayCombo.addActionListener(e -> updateAvailableRooms(
            roomCombo, 
            weekdayCombo.getSelectedIndex() + 1, 
            periodCombo.getSelectedIndex() + 1
        ));
        periodCombo.addActionListener(e -> updateAvailableRooms(
            roomCombo, 
            weekdayCombo.getSelectedIndex() + 1, 
            periodCombo.getSelectedIndex() + 1
        ));
        dialog.add(roomCombo, gbc);
        
        // 按钮面板
        gbc.gridx = 0; gbc.gridy = 5;
        gbc.gridwidth = 2;
        JPanel buttonPanel = new JPanel();
        JButton saveButton = new JButton("保存");
        JButton cancelButton = new JButton("取消");
        
        saveButton.addActionListener(e -> {
            SubjectTeacherItem selectedSubject = (SubjectTeacherItem)subjectCombo.getSelectedItem();
            ClassroomItem selectedRoom = (ClassroomItem)roomCombo.getSelectedItem();
            
            if (selectedSubject == null || selectedRoom == null) {
                JOptionPane.showMessageDialog(dialog, "请选择所有必要信息！");
                return;
            }
            
            int weekday = weekdayCombo.getSelectedIndex() + 1;
            int period = periodCombo.getSelectedIndex() + 1;
            
            if (scheduleService.scheduleClass(
                    selectedSubject.getId(), 
                    weekday, 
                    period, 
                    selectedRoom.getId())) {
                dialog.dispose();
                loadSchedule();
                JOptionPane.showMessageDialog(this, "排课成功！");
            } else {
                JOptionPane.showMessageDialog(dialog, "排课失败！", 
                    "错误", JOptionPane.ERROR_MESSAGE);
            }
        });
        
        cancelButton.addActionListener(e -> dialog.dispose());
        
        buttonPanel.add(saveButton);
        buttonPanel.add(cancelButton);
        dialog.add(buttonPanel, gbc);
        
        // 初始化第一个班级的课程
        if (classCombo.getItemCount() > 0) {
            ClassItem firstClass = (ClassItem)classCombo.getSelectedItem();
            loadSubjectTeachers(subjectCombo, firstClass.getId());
        }
        
        // 初始化可用教室
        updateAvailableRooms(
            roomCombo, 
            weekdayCombo.getSelectedIndex() + 1, 
            periodCombo.getSelectedIndex() + 1
        );
        
        dialog.pack();
        dialog.setLocationRelativeTo(this);
        dialog.setVisible(true);
    }
    
    private void loadSubjectTeachers(JComboBox<SubjectTeacherItem> combo, int classId) {
        combo.removeAllItems();
        List<Map<String, Object>> subjects = scheduleService.getUnscheduledSubjects(classId);
        for (Map<String, Object> subject : subjects) {
            combo.addItem(new SubjectTeacherItem(
                (Integer)subject.get("id"),
                subject.get("subjectName") + " - " + subject.get("teacherName")
            ));
        }
    }
    
    private void updateAvailableRooms(JComboBox<ClassroomItem> combo, int weekday, int period) {
        combo.removeAllItems();
        List<Map<String, Object>> rooms = scheduleService.getAvailableClassrooms(weekday, period);
        for (Map<String, Object> room : rooms) {
            String displayName = room.get("building").toString() + 
                               room.get("roomNumber").toString() + 
                               "(" + room.get("capacity").toString() + "人)";
            combo.addItem(new ClassroomItem(
                (Integer)room.get("id"),
                displayName
            ));
        }
    }
    
    private static class ClassItem {
        private int id;
        private String name;
        
        public ClassItem(int id, String name) {
            this.id = id;
            this.name = name;
        }
        
        public int getId() { return id; }
        
        @Override
        public String toString() { return name; }
    }
    
    private static class SubjectTeacherItem {
        private int id;
        private String name;
        
        public SubjectTeacherItem(int id, String name) {
            this.id = id;
            this.name = name;
        }
        
        public int getId() { return id; }
        
        @Override
        public String toString() { return name; }
    }
    
    private static class ClassroomItem {
        private int id;
        private String name;
        
        public ClassroomItem(int id, String name) {
            this.id = id;
            this.name = name;
        }
        
        public int getId() { return id; }
        
        @Override
        public String toString() { return name; }
    }
    
    private DefaultTableModel createEmptyTableModel() {
        // 创建空数据模型
        Object[][] data = new Object[ROW_HEADERS.length][COLUMN_NAMES.length];
        // 填充节次列
        for (int i = 0; i < ROW_HEADERS.length; i++) {
            data[i][0] = ROW_HEADERS[i];
        }
        
        // 创建表格模型，并设置为不可编辑
        DefaultTableModel model = new DefaultTableModel(data, COLUMN_NAMES) {
            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };
        
        return model;
    }
    
    // 添加清空课表的辅助方法
    private void clearScheduleTable() {
        for (int i = 0; i < scheduleTable.getRowCount(); i++) {
            for (int j = 1; j < scheduleTable.getColumnCount(); j++) {
                scheduleTable.setValueAt("", i, j);
            }
        }
    }
    
    // 添加一个统一的显示课表数据的方法
    private void displayScheduleData(List<Map<String, Object>> schedules) {
        // 清空现有数据
        clearScheduleTable();
        
        // 调试输出
        System.out.println("Current user role: " + userRole);
        
        // 显示课表数据
        for (Map<String, Object> schedule : schedules) {
            int weekday = (int) schedule.get("weekday");
            int period = (int) schedule.get("period");
            String subjectName = (String) schedule.get("subjectName");
            String secondLine;
            
            // 修改角色判断逻辑
            if (userRole != null && userRole.equals("TEACHER")) {
                secondLine = (String) schedule.get("className");  // 教师查看时显示班级
                System.out.println("Teacher view - Class name: " + secondLine);  // 调试输出
            } else {
                secondLine = (String) schedule.get("teacherName"); // 学生和管理员查看时显示教师
                System.out.println("Student/Admin view - Teacher name: " + secondLine);  // 调试输出
            }
            
            String classroom = (String) schedule.get("classroom");
            
            // 格式化课程信息
            String cellContent = String.format("<html>%s<br>%s<br>%s</html>",
                subjectName, secondLine, classroom);
            
            // 一大节课占用两小节
            int startPeriod = ((period - 1) * 2);
            scheduleTable.setValueAt(cellContent, startPeriod, weekday);
            scheduleTable.setValueAt(cellContent, startPeriod + 1, weekday);
        }
    }
    
    // 更新标题的方法
    private void updateTitle(String title) {
        // 遍历组件找到标题标签并更新
        for (Component comp : getComponents()) {
            if (comp instanceof JPanel) {
                JPanel panel = (JPanel) comp;
                for (Component innerComp : panel.getComponents()) {
                    if (innerComp instanceof JPanel) {
                        JPanel innerPanel = (JPanel) innerComp;
                        for (Component titleComp : innerPanel.getComponents()) {
                            if (titleComp instanceof JLabel) {
                                ((JLabel) titleComp).setText(title);
                                break;
                            }
                        }
                    }
                }
            }
        }
    }
    
    // 显示未排课班级的方法
    private void showUnscheduledClasses() {
        List<Map<String, Object>> unscheduledSubjects = scheduleService.getUnscheduledSubjects(null);
        if (unscheduledSubjects.isEmpty()) {
            JOptionPane.showMessageDialog(this, "所有班级课程都已排课！");
            return;
        }
        
        // 创建显示未排课信息的对话框
        JDialog dialog = new JDialog((Frame)SwingUtilities.getWindowAncestor(this), "未排课信息", true);
        dialog.setLayout(new BorderLayout(10, 10));
        
        // 创建表格模型
        String[] columnNames = {"班级", "课程", "教师"};
        DefaultTableModel model = new DefaultTableModel(columnNames, 0) {
            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };
        
        // 填充数据
        for (Map<String, Object> subject : unscheduledSubjects) {
            model.addRow(new Object[]{
                subject.get("className"),
                subject.get("subjectName"),
                subject.get("teacherName")
            });
        }
        
        // 创建表格
        JTable table = new JTable(model);
        table.setFont(CONTENT_FONT);
        table.getTableHeader().setFont(TITLE_FONT);
        table.setRowHeight(25);
        
        // 添加到对话框
        dialog.add(new JScrollPane(table), BorderLayout.CENTER);
        
        // 添加关闭按钮
        JButton closeButton = new JButton("关闭");
        closeButton.setFont(CONTENT_FONT);
        closeButton.addActionListener(e -> dialog.dispose());
        
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(closeButton);
        dialog.add(buttonPanel, BorderLayout.SOUTH);
        
        // 设置对话框大小和位置
        dialog.setSize(600, 400);
        dialog.setLocationRelativeTo(this);
        dialog.setVisible(true);
    }
} 